package com.tjvib.view.activity;

import static com.tjvib.Constants.METHOD_CENSUS;
import static com.tjvib.Constants.METHOD_DAMPING;
import static com.tjvib.Constants.METHOD_FFT;
import static com.tjvib.Constants.METHOD_FREQ;
import static com.tjvib.Constants.METHOD_HUMAN;
import static com.tjvib.Constants.METHOD_MASS;
import static com.tjvib.Constants.METHOD_VSA;

import android.app.LoaderManager;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;

import com.bumptech.glide.Glide;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.LegendRenderer;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.DataPointInterface;
import com.jjoe64.graphview.series.LineGraphSeries;
import com.jjoe64.graphview.series.OnDataPointTapListener;
import com.jjoe64.graphview.series.PointsGraphSeries;
import com.jjoe64.graphview.series.Series;
import com.tjvib.R;
import com.tjvib.base.BaseActivity;
import com.tjvib.util.LogUtil;
import com.tjvib.util.Manager.DataSetManager;
import com.tjvib.common.Callback;
import com.tjvib.presenter.InterceptPresenter;
import com.tjvib.sensor.SensorData;
import com.tjvib.util.Manager.AppManager;
import com.tjvib.util.ToastUtil;
import com.tjvib.view.dialog.NotFoundDialog;

import java.util.ArrayList;
import java.util.List;

public class InterceptActivity extends BaseActivity<InterceptPresenter> {

    private Button int_btn_start;
    private EditText int_et_start, int_et_end;
    private Spinner int_sp_sensor;
    private CheckBox int_cb_x, int_cb_y, int_cb_z;
    private GraphView int_gv_data;
    private ImageView int_iv_end, int_iv_start;

    private String sensorSelect = "";
    private double timestampSelect = 0.0d;
    private List<String> sensorList = new ArrayList<>();
    private boolean isCheck = false;
    List<? extends SensorData> sensorDataList = new ArrayList<>();
    LineGraphSeries<DataPoint> mSeries1 = new LineGraphSeries<>(),
            mSeries2 = new LineGraphSeries<>(),
            mSeries3 = new LineGraphSeries<>();
    PointsGraphSeries<DataPoint> pSeries = new PointsGraphSeries<>();

    OnDataPointTapListener onDataPointTapListener = new OnDataPointTapListener() {
        @Override
        public void onTap(Series series, DataPointInterface dataPoint) {
            isCheck = true;
            timestampSelect = dataPoint.getX();
            if (int_et_start.isEnabled()) int_et_start.setText(String.valueOf(dataPoint.getX()));
            if (int_et_end.isEnabled()) int_et_end.setText(String.valueOf(dataPoint.getX()));
            pSeries.resetData(new DataPoint[]{new DataPoint(dataPoint.getX(), dataPoint.getY())});
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected int initLayout() {
        return R.layout.activity_intercept;
    }

    @Override
    protected boolean initView() {
        int_gv_data = findViewById(R.id.int_gv_data);

        int_et_start = findViewById(R.id.int_et_start);
        int_et_end = findViewById(R.id.int_et_end);

        int_iv_start = findViewById(R.id.int_iv_start);
        int_iv_start.setOnClickListener(v -> {
            if (int_et_start.isEnabled()) {
                if (isCheck) int_et_start.setText(String.valueOf(timestampSelect));
                int_et_start.setEnabled(false);
                Glide.with(InterceptActivity.this).load(R.mipmap.finish_on).into(int_iv_start);
                if(getIntent().getStringExtra("METHOD").equals(METHOD_MASS))
                    int_et_end.setText(String.valueOf(Double.parseDouble(int_et_start.getText().toString().trim())+20.0));
            } else {
                int_et_start.setEnabled(true);
                Glide.with(InterceptActivity.this).load(R.mipmap.finish_off).into(int_iv_start);
            }
        });

        int_iv_end = findViewById(R.id.int_iv_end);
        int_iv_end.setOnClickListener(v -> {
            if (int_et_end.isEnabled()) {
                if (isCheck) int_et_end.setText(String.valueOf(timestampSelect));
                int_et_end.setEnabled(false);
                Glide.with(InterceptActivity.this).load(R.mipmap.finish_on).into(int_iv_end);
            } else {
                int_et_end.setEnabled(true);
                Glide.with(InterceptActivity.this).load(R.mipmap.finish_off).into(int_iv_end);
            }
        });

        if(getIntent().getStringExtra("METHOD").equals(METHOD_MASS)){
            int_iv_end.setVisibility(View.INVISIBLE);
            int_et_end.setEnabled(false);
            ToastUtil.show("本分析方法固定截取时间为20s！");
        }

        int_btn_start = findViewById(R.id.int_btn_start);
        int_btn_start.setOnClickListener(v -> {
            if(int_et_start.getText().toString().trim().equals("") || int_et_end.getText().toString().trim().equals("")){
                ToastUtil.show("起始时间/结束时间不能为空！");
                return;
            }
            double start = Double.parseDouble(int_et_start.getText().toString().trim());
            double end = Double.parseDouble(int_et_end.getText().toString().trim());

            if(getIntent().getStringExtra("METHOD").equals(METHOD_MASS)) {
                end = sensorDataList.get(sensorDataList.size() - 1).timestamp;
                if(start + 20.0 >= sensorDataList.get(sensorDataList.size()-1).timestamp) {
                    ToastUtil.show("当前截取时间不超过20.0s，不支持使用本分析方法！");
                    return;
                }
            }else if(getIntent().getStringExtra("METHOD").equals(METHOD_FREQ)){
                if(start + 10.24 >= sensorDataList.get(sensorDataList.size()-1).timestamp) {
                    ToastUtil.show("当前截取时间不超过10.24s，不支持使用本分析方法！");
                    return;
                }
            }

            if (start >= end) {
                showErrorDialog("起始时间不能大于或等于结束时间");
            } else {
                DataSetManager.getInstance().cutDataSet(start, end);
                switch (getIntent().getStringExtra("METHOD")) {
                    case METHOD_FFT:
                        Intent intent0 = new Intent(this, FftActivity.class);
                        intent0.putExtra("METHOD", METHOD_FFT);
                        this.startActivity(intent0);
                        break;
                    case METHOD_DAMPING:
                        Intent intent1 = new Intent(this, DampingActivity.class);
                        intent1.putExtra("METHOD", METHOD_DAMPING);
                        this.startActivity(intent1);
                        break;
                    case METHOD_CENSUS:
                        Intent intent2 = new Intent(this, CensusActivity.class);
                        intent2.putExtra("METHOD", METHOD_CENSUS);
                        this.startActivity(intent2);
                        break;
                    case METHOD_HUMAN:
                        Intent intent3 = new Intent(this, ParamActivity.class);
                        intent3.putExtra("METHOD", METHOD_HUMAN);
                        this.startActivity(intent3);
                        break;
                    case METHOD_VSA:
                        Intent intent4 = new Intent(this, VsaActivity.class);
                        intent4.putExtra("METHOD", METHOD_VSA);
                        this.startActivity(intent4);
                        break;
                    case METHOD_FREQ:
                        Intent intent5 = new Intent(this, FreqDampingActivity.class);
                        intent5.putExtra("METHOD", METHOD_FREQ);
                        intent5.putExtra("T0", Double.parseDouble(int_et_start.getText().toString().trim()));
                        intent5.putExtra("T1", Double.parseDouble(int_et_end.getText().toString().trim()));
                        this.startActivity(intent5);
                        break;
                    case METHOD_MASS:
                        Intent intent6 = new Intent(this, MassActivity.class);
                        intent6.putExtra("METHOD", METHOD_MASS);
                        intent6.putExtra("T0", Double.parseDouble(int_et_start.getText().toString().trim()));
                        this.startActivity(intent6);
                        break;
                }
                AppManager.getInstance().finishActivity();
            }
        });

        int_sp_sensor = findViewById(R.id.int_sp_sensor);

        int_cb_x = findViewById(R.id.int_cb_x);
        int_cb_y = findViewById(R.id.int_cb_y);
        int_cb_z = findViewById(R.id.int_cb_z);
        int_cb_x.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) int_gv_data.addSeries(mSeries1);
            else int_gv_data.removeSeries(mSeries1);
        });
        int_cb_y.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) int_gv_data.addSeries(mSeries2);
            else int_gv_data.removeSeries(mSeries2);
        });
        int_cb_z.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) int_gv_data.addSeries(mSeries3);
            else int_gv_data.removeSeries(mSeries3);
        });
        return true;
    }

    @Override
    protected boolean initData() {
        ToastUtil.show("初始化图表，请稍等");
        presenter.initDataSetContent(new Callback() {
            @Override
            public void onSuccess(String message, String data) {
                initSpinner();
            }

            @Override
            public void onFail(String message, String data) {
                showGetDataSetContentFailedDialog();
            }

            @Override
            public void onError(String message, String data) {
                showParseFailedDialog(message);
            }
        });

        mSeries1.setOnDataPointTapListener(onDataPointTapListener);
        mSeries2.setOnDataPointTapListener(onDataPointTapListener);
        mSeries3.setOnDataPointTapListener(onDataPointTapListener);

        return true;
    }

    private void initSpinner() {
        runOnUiThread(() -> {
            sensorList = DataSetManager.getInstance().getSensorList();
            sensorSelect = sensorList.get(0);
            int_sp_sensor.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    LogUtil.i("选择了第" + position + "个传感器");
                    sensorSelect = sensorList.get(position);
                    removeGraph();
                    drawGraph();
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                }
            });

            SpinnerAdapter spinnerAdapter = new ArrayAdapter<>(InterceptActivity.this,
                    R.layout.item_spinner_dropdown, sensorList);
            int_sp_sensor.setPrompt("选择传感器");
            int_sp_sensor.setAdapter(spinnerAdapter);
            int_sp_sensor.setSelection(0);
            int_cb_x.setChecked(true);
            int_cb_y.setChecked(true);
            int_cb_z.setChecked(true);
        });
    }

    @Override
    protected InterceptPresenter genPresenter() {
        return new InterceptPresenter(this);
    }


    public void initGraphView() {
        runOnUiThread(() -> {
            mSeries1.resetData(new DataPoint[]{});
            mSeries2.resetData(new DataPoint[]{});
            mSeries3.resetData(new DataPoint[]{});
            double miny = Double.MAX_VALUE, maxy = Double.MIN_VALUE;
            for (int m = 1; m < sensorDataList.size(); m++) {
                SensorData data = sensorDataList.get(m);
                float[] dataToShow = new float[3];
                int i = 0;
                while (i < 3) {
                    dataToShow[i] = data.acc[i];
                    maxy = Math.max(dataToShow[i], maxy);
                    miny = Math.min(dataToShow[i], miny);
                    i += 1;
                }
//                LogUtil.i("data.timestamp="+data.timestamp+data.localtime);
                mSeries1.appendData(new DataPoint(data.timestamp, dataToShow[0]), true, Integer.MAX_VALUE);
                mSeries2.appendData(new DataPoint(data.timestamp, dataToShow[1]), true, Integer.MAX_VALUE);
                mSeries3.appendData(new DataPoint(data.timestamp, dataToShow[2]), true, Integer.MAX_VALUE);
            }

            int_gv_data.getViewport().setScrollable(true);
            int_gv_data.getViewport().setScalable(true);
            if(sensorDataList.size() != 0) {
                int_gv_data.getViewport().setMinX(0.0D);
                int_gv_data.getViewport().setMaxX(sensorDataList.get(sensorDataList.size() - 1).timestamp);
                int_gv_data.getViewport().setMaxY(maxy);
                int_gv_data.getViewport().setMinY(miny);
            }
        });
    }


    private void removeGraph() {
        runOnUiThread(() -> {
            int_gv_data.removeAllSeries();
            int_cb_x.setChecked(false);
            int_cb_y.setChecked(false);
            int_cb_z.setChecked(false);
            int_cb_x.setEnabled(false);
            int_cb_y.setEnabled(false);
            int_cb_z.setEnabled(false);
        });
    }


    private void drawGraph() {
        if (DataSetManager.getInstance().getDataSetInfo().getType().equals("local"))
            sensorDataList = DataSetManager.getInstance().getDataSetContent(-1);
        else
            sensorDataList = DataSetManager.getInstance().getDataSetContent(Integer.parseInt(sensorSelect));
        initGraphView();
        runOnUiThread(() -> {
            mSeries1.setThickness(3);
            mSeries2.setThickness(3);
            mSeries3.setThickness(3);
            pSeries.setSize(10);
            pSeries.setColor(Color.BLACK);
            mSeries1.setColor(Color.BLUE);
            mSeries2.setColor(Color.GREEN);
            mSeries3.setColor(Color.RED);
            int_gv_data.setBackgroundColor(Color.WHITE);
            mSeries1.setTitle("X");
            mSeries2.setTitle("Y");
            mSeries3.setTitle("Z");
            pSeries.setTitle("Clicked");
            int_gv_data.getLegendRenderer().setBackgroundColor(Color.TRANSPARENT);
            int_gv_data.getLegendRenderer().setVisible(true);
            int_gv_data.getLegendRenderer().setTextSize(18);
            int_gv_data.getLegendRenderer().setTextColor(R.color.main_grey_2);
            int_gv_data.getLegendRenderer().setAlign(LegendRenderer.LegendAlign.TOP);
            int_gv_data.getGridLabelRenderer().setHorizontalAxisTitle("时间(s)");
            int_gv_data.getGridLabelRenderer().setVerticalAxisTitle("幅值(g)");
            int_gv_data.getGridLabelRenderer().setHorizontalAxisTitleTextSize(24);
            int_gv_data.getGridLabelRenderer().setVerticalAxisTitleTextSize(24);

            int_cb_x.setChecked(true);
            int_cb_y.setChecked(true);
            int_cb_z.setChecked(true);
            int_cb_x.setEnabled(true);
            int_cb_y.setEnabled(true);
            int_cb_z.setEnabled(true);

            int_gv_data.addSeries(pSeries);

            float startTime = sensorDataList.get(1).timestamp;
            float endTime = sensorDataList.get(sensorDataList.size() - 1).timestamp;
            int_et_start.setText(String.valueOf(startTime));
            int_et_end.setText(String.valueOf(endTime));

            if (getIntent().getStringExtra("METHOD").equals(METHOD_MASS)){
                if(DataSetManager.getInstance().getSensorList().size() <= 1)
                    showErrorDialogFinish("当前数据集只包含一个传感器的数据，不支持使用本分析方法！");
                else if(endTime - startTime < 20)
                    showErrorDialogFinish("当前数据集不超过20.0s，不支持使用本分析方法！");
            }else if (getIntent().getStringExtra("METHOD").equals(METHOD_FREQ)){
                if(endTime - startTime < 10.24)
                    showErrorDialogFinish("当前数据集不超过10.24s，不支持使用本分析方法！");
            } else if (getIntent().getStringExtra("METHOD").equals(METHOD_HUMAN)) {
                if (DataSetManager.getInstance().getSensorList().size() <= 1)
                    showErrorDialogFinish("当前数据集只包含一个传感器的数据，不支持使用本功能！");
            }
        });
    }


    public void showGetDataSetContentFailedDialog() {
        runOnUiThread(() -> {
            NotFoundDialog notFoundDialog = new NotFoundDialog(InterceptActivity.this);
            notFoundDialog.showDialog("获取服务器数据失败，请稍后重试",
                    view -> {
                        if(notFoundDialog.isShowing()) notFoundDialog.dismiss();
                        AppManager.getInstance().finishActivity();
                    });
        });
    }


    public void showParseFailedDialog(String message) {
        runOnUiThread(() -> {
            NotFoundDialog notFoundDialog = new NotFoundDialog(InterceptActivity.this);
            notFoundDialog.showDialog(message,
                    view -> {
                        notFoundDialog.dismiss();
                        AppManager.getInstance().finishActivity();
                    });
        });
    }
}